package mysgoog.bot.algo;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;

import mysgoog.board.Board;
import mysgoog.board.Dragon;
import mysgoog.board.DragonBoard;
import mysgoog.board.Worm;
import mysgoog.bot.ValuedPos;
import mysgoog.gtp.Color;

public class Cut {
	public static int cut(Board board, Color player) {
		if (!(board instanceof DragonBoard))
			return -1;
		DragonBoard dragonBoard = (DragonBoard) board;
		List<Integer> cutList;
		if (player == Color.WHITE)
			cutList = dragonBoard.black_conn;
		else
			cutList = dragonBoard.white_conn;
		int bestPos = -1;
		int bestScore = -1;
		int score = 1;
		List<Worm> currentWorm = null;
		for (Integer i : cutList) {
			currentWorm = new ArrayList<Worm>();
			List<Integer> adjacent = dragonBoard.getAround(i);
			for (int j : adjacent) {
				if (dragonBoard.wormAt(j) == null)
					continue;
				if (dragonBoard.wormAt(j).color == player)
					continue;
				if (!currentWorm.contains(dragonBoard.wormAt(j)))
					currentWorm.add(dragonBoard.wormAt(j));
			}
			score = getScore(currentWorm, dragonBoard);
			if (score > bestScore) {
				bestScore = score;
				bestPos = i;
			}
		}
		if (isValid(bestScore))
			return bestPos;
		return -1;
	}

	public static int connect(Board board, Color player) {
		if (!(board instanceof DragonBoard))
			return -1;
		DragonBoard dragonBoard = (DragonBoard) board;
		List<Integer> cutList;
		if (player == Color.WHITE)
			cutList = dragonBoard.white_conn;
		else
			cutList = dragonBoard.black_conn;
		int bestPos = -1;
		int bestScore = -1;
		int score = 1;
		List<Worm> currentWorm = null;
		for (Integer i : cutList) {
			currentWorm = new ArrayList<Worm>();
			List<Integer> adjacent = dragonBoard.getAround(i);
			for (int j : adjacent) {
				if (dragonBoard.wormAt(j) == null)
					continue;
				if (dragonBoard.wormAt(j).color != player)
					continue;
				if (!currentWorm.contains(dragonBoard.wormAt(j)))
					currentWorm.add(dragonBoard.wormAt(j));
			}
			score = getScore(currentWorm, dragonBoard);
			if (score > bestScore) {
				bestScore = score;
				bestPos = i;
			}
		}
		if (isValid(bestScore))
			return bestPos;
		return -1;
	}

	public LinkedList<ValuedPos> cutList(Board board, Color player) {
		if (!(board instanceof DragonBoard))
			return null;
		DragonBoard dragonBoard = (DragonBoard) board;
		List<Integer> cutList;
		if (player == Color.WHITE)
			cutList = dragonBoard.black_conn;
		else
			cutList = dragonBoard.white_conn;

		LinkedList<ValuedPos> ret = new LinkedList<ValuedPos>();
		int score = 1;
		List<Worm> currentWorm = null;
		for (Integer i : cutList) {
			currentWorm = new ArrayList<Worm>();
			List<Integer> adjacent = dragonBoard.getAround(i);
			for (int j : adjacent) {
				if (dragonBoard.wormAt(j) == null)
					continue;
				if (dragonBoard.wormAt(j).color == player)
					continue;
				if (!currentWorm.contains(dragonBoard.wormAt(j)))
					currentWorm.add(dragonBoard.wormAt(j));
			}
			score = getScore(currentWorm, dragonBoard);
			ret.add(new ValuedPos(i, score));
		}

		return ret;
	}

	public LinkedList<ValuedPos> connList(Board board, Color player) {
		if (!(board instanceof DragonBoard))
			return null;
		DragonBoard dragonBoard = (DragonBoard) board;
		List<Integer> cutList;
		if (player == Color.WHITE)
			cutList = dragonBoard.white_conn;
		else
			cutList = dragonBoard.black_conn;

		LinkedList<ValuedPos> ret = new LinkedList<ValuedPos>();
		int score = 1;
		List<Worm> currentWorm = null;
		for (Integer i : cutList) {
			currentWorm = new ArrayList<Worm>();
			List<Integer> adjacent = dragonBoard.getAround(i);
			for (int j : adjacent) {
				if (dragonBoard.wormAt(j) == null)
					continue;
				if (dragonBoard.wormAt(j).color == player)
					continue;
				if (!currentWorm.contains(dragonBoard.wormAt(j)))
					currentWorm.add(dragonBoard.wormAt(j));
			}
			score = getScore(currentWorm, dragonBoard);
			ret.add(new ValuedPos(i, score));
		}

		return ret;
	}

	private static int getScore(List<Worm> worms, DragonBoard db) {
		int score = 1;
		HashSet<Dragon> avoidDup = new HashSet<Dragon>();
		if (worms.size() != 0)
			for (Worm worm : worms)
				if (!avoidDup.contains(db.dragonAt(worm.getOne()))) {
					avoidDup.add(db.dragonAt(worm.getOne()));
					score *= worm.size();
				}

		if (avoidDup.size() <= 1)
			return 1;
		return score;
	}

	private static boolean isValid(int score) {
		return (score > 1);
	}

}
